package indi.h.mlx.sql;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.google.common.base.Optional;

import indi.h.mlx.sql.inter.SQLParam;
import indi.h.mlx.sql.inter.SQLRule;
import indi.h.mlx.sql.inter.SQLStructure.SqlType;
import indi.h.mlx.sql.items.SQL;
import indi.h.mlx.sql.items.SQLData;
import indi.h.mlx.sql.util.SQLUtil;

public class WhereSqlRule implements SQLRule<List<SQLData>, SQL> {
	// 自定义参数
	private List<SQLParam> params;
	// 排序参数
	private String orderBy;
	// 分组参数
	private String groupBy;
	// 获取行数参数
	private String limit;
	// 语句类型
	private SqlType sqlType;

	public static String C_PARAMS = "c_params";
	public static String GROUP_BY = "group_by";
	public static String ORDER_BY = "order_by";
	public static String LIMIT = "limit";
	public static String SQL_TYPE = "sql_type";

	@Override
	public SQL rule(List<SQLData> data) {
		// TODO Auto-generated method stub
		data = Optional.fromNullable(data).or(new ArrayList<>());
		if (this.sqlType == SqlType.SELECT)
			return selectWhere(data);
		else if (this.sqlType == SqlType.INSERT)
			return null;
		return upDelWhere(data);
	}

	private SQL selectWhere(List<SQLData> data) {
		SQL createSQL = createSQL(data);
		createSQL.setSql(formatSql(createSQL.getSql() + " " + getWhereEnd()));
		return createSQL;
	}

	private String formatSql(String sql) {
		String trim = sql.trim();
		if (trim.startsWith("where")) {
			return trim;
		}
		if (trim.equals("") || trim.equals("and") || trim.equals("or")) {
			return "";
		}
		if (trim.startsWith("and")) {
			return "where" + trim.replaceAll("^and", "");
		}
		if (trim.startsWith("or")) {
			return "where" + trim.replaceAll("^or", "");
		}
		if (trim.startsWith("`")) {
			return "where " + trim;
		}
		return "";
	}

	private SQL upDelWhere(List<SQLData> data) {
		SQL createSQL = createSQL(data);
		createSQL.setSql(formatSql(createSQL.getSql()));
		return createSQL;
	}

	private SQL createSQL(List<SQLData> data) {
		SQL createDefaultData = createDefaultData(data);
		SQL createCustomWhere = createCustomWhere();
		return SQLUtil.sqlJoins(createDefaultData, createCustomWhere);
	}

	/**
	 * 获取结束筛选数据
	 * 
	 * @return
	 */
	private String getWhereEnd() {
		StringBuilder sb = new StringBuilder();
		if (Optional.fromNullable(this.groupBy).isPresent())
			sb.append(this.groupBy);
		sb.append(" ");
		if (Optional.fromNullable(this.orderBy).isPresent())
			sb.append(this.orderBy);
		sb.append(" ");
		if (Optional.fromNullable(this.limit).isPresent())
			sb.append(this.limit);
		return sb.toString().trim();
	}

	/**
	 * 获取自定义筛选参数
	 * 
	 * @return
	 */
	private SQL createCustomWhere() {
		List<Object> dl = new ArrayList<>();
		StringBuilder sb = new StringBuilder();
		for (SQLParam sp : params) {
			sb.append(sp.getRelation());
			sb.append(" ");
			sb.append(sp.getParam());
			sb.append(" ");
			dl.addAll(Arrays.asList(sp.getValues()));
		}
		return new SQL(sb.toString().trim(), dl.toArray());
	}

	/**
	 * 默认数据构建方法
	 * 
	 * @param s
	 * @return
	 */
	private SQL createDefaultData(List<SQLData> s) {
		StringBuilder sb = new StringBuilder();
		Object[] objects = new Object[s.size()];
		int i = 0;
		for (SQLData sd : s) {
			sb.append(sd.getRelation());
			sb.append(" ");
			sb.append(sd.getParam());
			sb.append(" ");
			objects[i] = sd.getValue();
			i++;
		}
		return new SQL(sb.toString().trim(), objects);
	}

	@Override
	public void init(Map<String, Object> m) {
		// TODO Auto-generated method stub
		this.params = (List<SQLParam>) Optional.fromNullable(m.get(C_PARAMS)).or(new ArrayList<>());
		this.orderBy = (String) Optional.fromNullable(m.get(ORDER_BY)).or("");
		this.groupBy = (String) Optional.fromNullable(m.get(GROUP_BY)).or("");
		this.limit = (String) Optional.fromNullable(m.get(LIMIT)).or("");
		this.sqlType = (SqlType) Optional.of(m.get(SQL_TYPE)).get();
	}

}
